/*
 * Copyright (c) 2010-2011 Josef Hardi <josef.hardi@gmail.com>
 * Copyright (c) 2010 Piotr Zagawa <piotr.zagawa@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package id.duapuluhdua.dakidaki.loader;

import java.util.Observable;
import java.util.Observer;

import id.duapuluhdua.dakidaki.MainState;
import id.duapuluhdua.dakidaki.activities.ActivityMain;
import id.duapuluhdua.dakidaki.gps.GpsLocation;
import id.duapuluhdua.dakidaki.gps.GpsLocationStatus;
import id.duapuluhdua.dakidaki.map.GeoPoint;

/**
 *
 */
public class DataStats extends Observable implements Observer
{
  /** Constants */
  private final Boolean bDataAccessMutex = false;

  public final Boolean bUpdatedMode = false;
  public final Boolean bUpdatedLocation = false;

  /** Fields */
  private MainState mState;
  private GpsLocationStatus mGpsLocationStatus;

  // Statistic objects
  private TrackItem mTrackItem;
  private GpsLocation mGpsLocation;
  private GeoPoint mLocationPoint;
  private int mAltitude;

  // Track items data
  private DataStatsTrackCollection mTracksStats;

  /**
   * The constructor.
   *
   * @param parent
   * @param gpsLocationStatus
   */
  public DataStats(ActivityMain parent, GpsLocationStatus gpsLocationStatus)
  {
    mState = parent.getMainState();
    mGpsLocationStatus = gpsLocationStatus;

    mTracksStats = new DataStatsTrackCollection();
    mGpsLocation = new GpsLocation();
    mLocationPoint = new GeoPoint();

    // Watch state object for UI mode change
    mState.addObserver(this);

    // Watch for location change
    gpsLocationStatus.addObserver(this);
  }

  @Override
  public void update(Observable observable, Object data)
  {
    if (observable == mState) {
      if (data == MainState.UI_MODE_UPDATE) {
        updateObjectsSelection();
      }
    }

    if (observable == mGpsLocationStatus) {
      if (data == GpsLocationStatus.STATE_NEW_GPS_LOCATION) {
        updateLocation();
      }
    }
  }

  public boolean isLocationEnabled()
  {
    return mGpsLocation.isEnabled();
  }

  private void updateObjectsSelection()
  {
    synchronized (bDataAccessMutex)
    {
      // Get selected objects
      mTrackItem = null;

      final long trackId = mState.getSelectedTrack();

      if (trackId != -1) {
        mTrackItem = ActivityMain.loader.getSelectedTrack();
      }
      setChanged();
      notifyObservers(bUpdatedMode);
    }
  }

  private void updateLocation()
  {
    synchronized (bDataAccessMutex)
    {
      // get current location
      ActivityMain.loader.getGpsLocationStatus().copyCurrent(mGpsLocation);

      if (mGpsLocation.isEnabled()) {
        mLocationPoint.wgsLon = mGpsLocation.wgsLon;
        mLocationPoint.wgsLat = mGpsLocation.wgsLat;
        mAltitude = mGpsLocation.altitude;
      }

      setChanged();
      notifyObservers(bUpdatedLocation);
    }
  }

  public int getTrackTimeInSeconds()
  {
    int value = -1;
    synchronized(bDataAccessMutex)
    {
      if (mTrackItem != null) {
        value = mTrackItem.dataTrack.getTotalTimeInSeconds();
      }
    }
    return value;
  }

  public double getTotalDistanceInMeters()
  {
    double value = -1;
    synchronized(bDataAccessMutex)
    {
      if (mTrackItem != null) {
        value = mTrackItem.getTotalDistanceInMeters();
      }
    }
    return value;
  }

  /**
   * @return
   */
  public int getAltitude()
  {
    int value = -1;
    synchronized(bDataAccessMutex)
    {
      if (isLocationEnabled()) {
          value = mAltitude;
      }
    }
    return value;
  }
}
